package com.fzu.thirdpartyservice.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fzu.commonutil.util.ApiException;
import com.fzu.commonutil.util.ErrorEnum;
import com.fzu.commonutil.util.AddressComponent;
import com.fzu.commonutil.util.Coordinate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;


/**
 * 地图工具
 * @author IT00ZYQ
 * @date 2021/6/9 23:11
 **/
@Component
@Slf4j
public class MapUtil {
    @Resource
    private RestTemplate restTemplate;
    private final static String AK = "YIwv7vc5O3G3mINazmEMl5Q9WjMItUzc";
    private final static String URL_TEMPLATE = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=%s&output=json&coordtype=wgs84ll&location=%f,%f";
    private final static String ADDRESS_TO_COORDINATE_URL_TEMPLATE = "https://api.map.baidu.com/geocoding/v3/?address=%s&output=json&ak=%s";
    private final static String DISTANCE_URL_TEMPLATE = "https://api.map.baidu.com/routematrix/v2/riding?output=json&origins=%s,%s&destinations=%s,%s&ak=%s";


    /**
     * 根据经纬度调用百度地图api获取具体地理信息
     * @param longitude 经度
     * @param latitude 纬度
     * @return AddressMessage
     */
    public AddressComponent getAddress(Double longitude, Double latitude) {
        // 请求成功是AddressComponent返回一定格式的json
        final String successPre = "{\"status\"";
        // 百度地图的授权ak
        String url = String.format(URL_TEMPLATE, AK, latitude, longitude);
        log.info("调用百度地图API:{}", url);
        String res = restTemplate.getForObject(url, String.class);
        log.info("经纬度:{},{} -> 结果:{}", longitude, latitude, res);
        if (res == null || !res.startsWith(successPre)) {
            throw new ApiException(ErrorEnum.LOCATION_FAIL);
        }
        JSONObject jsonObject = JSON.parseObject(res);
        JSONObject result = jsonObject.getJSONObject("result");
        JSONObject addressComponent = result.getJSONObject("addressComponent");
        return AddressComponent.builder()
                .city(addressComponent.getString("city"))
                .province(addressComponent.getString("province"))
                .district(addressComponent.getString("district"))
                .street(addressComponent.getString("street"))
                .town(addressComponent.getString("town"))
                .address(result.getString("formatted_address"))
                .build();
    }


    /**
     * 根据地址调用百度地图api获取具体经纬度信息
     * @param address 详细地址
     * @return AddressMessage
     */
    public Coordinate getCoordinate(String address) {
        // 请求成功是返回一定格式的json
        final String successPre = "{\"status\"";
        // 百度地图的授权ak
        String url = String.format(ADDRESS_TO_COORDINATE_URL_TEMPLATE, address, AK);
        log.info("地址转经纬度 => 调用百度地图API: {}", url);
        String res = restTemplate.getForObject(url, String.class);
        log.info("地址:{} -> 结果:{}", address, res);
        if (res == null || !res.startsWith(successPre)) {
            log.warn("地址转经纬度失败: {}", address);
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(res);
        JSONObject result = jsonObject.getJSONObject("result");
        JSONObject location = result.getJSONObject("location");
        return Coordinate.builder()
                .lat(location.getDouble("lat"))
                .lng(location.getDouble("lng"))
                .build();
    }

    /**
     * 获取两个经纬度的距离
     * @param startLng
     * @param startLat
     * @param endLng
     * @param endLat
     * @return
     */
    public Double getDistance(Double startLng, Double startLat, Double endLng, Double endLat) {
        // 请求成功是返回一定格式的json
        final String successPre = "{\"status\"";
        // 百度地图的授权ak
        String url = String.format(DISTANCE_URL_TEMPLATE, startLng, startLat, endLng, endLat, AK);
        log.info("经纬度距离计算 => 调用百度地图API: {}", url);
        String res = restTemplate.getForObject(url, String.class);
        log.info("结果:{}", res);
        if (res == null || !res.startsWith(successPre)) {
            log.warn("经纬度距离计算");
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(res);
        JSONArray result = jsonObject.getJSONArray("result");
        JSONObject distanceResult = result.getJSONObject(0);
        JSONObject distance = distanceResult.getJSONObject("distance");
        return distance.getDouble("value");
    }

}
